/*
 * Losetup command.
 */

#define main losetupcmd

#ifdef USE_GLIBC_STDIO
#include <stdio.h>

#include "../mystring.h"
#else
#include "bltin.h"
#endif

#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>

#ifndef	dev_t
#define	dev_t	dev_t
#endif
#include <linux/loop.h>

int
main(int argc, const char *const *argv)
{
	int loopfd, targfd;
	struct loop_info loopInfo;

	if ( argc < 3 )
		return 1;

	if ( !strcmp( argv[1], "-d" ) )
	{
		loopfd = open( argv[2], O_RDONLY );
		if ( loopfd < 0 )
		{
			fprintf( stderr, "losetup: error opening %s: %s\n", argv[2], strerror(errno) );
			return 1;
		}

		if ( ioctl(loopfd, LOOP_CLR_FD, 0) < 0 )
		{
			fprintf( stderr, "losetup: error unassociating device: %s\n", strerror(errno) );
			close( loopfd );
			return 1;
		}

		close( loopfd );
		return 0;
	}

	loopfd = open( argv[1], O_RDONLY );
	if ( loopfd < 0 )
	{
		fprintf( stderr, "losetup: error opening %s: %s\n", argv[1], strerror(errno) );
		return 1;
	}

	targfd = open( argv[2], O_RDONLY );
	if ( targfd < 0 )
	{
		fprintf( stderr, "losetup: error opening %s: %s\n", argv[2], strerror(errno) );
		close( loopfd );
		return 1;
	}

	if ( ioctl(loopfd, LOOP_SET_FD, targfd) < 0 )
	{
		fprintf( stderr, "losetup: error setting up loopback device: %s\n", strerror(errno) );
		close( loopfd );
		close( targfd );
		return 1;
	}

	memset(&loopInfo, 0, sizeof(loopInfo));
	strcpy(loopInfo.lo_name, argv[2]);

	if ( ioctl(loopfd, LOOP_SET_STATUS, &loopInfo) < 0 )
		fprintf( stderr, "losetup: error setting up loopback device: %s\n", strerror(errno) );

	close( loopfd );
	close( targfd );

	return 0;
}
